import os
import sys
from PIL import ImageQt, Image
from pyzbar.pyzbar import decode
from ui.ui import MainUI, WScreenShot
from utils.data import CodeTemplate, DataJson, Code
from PySide6.QtWidgets import QMainWindow, QApplication, QMessageBox, QFileDialog

if getattr(sys, "frozen", False):
    absPath = os.path.dirname(os.path.abspath(sys.executable))
elif __file__:
    absPath = os.path.dirname(os.path.abspath(__file__))

datapath = os.path.join(absPath, ".\data")
if not os.path.exists(os.path.join(absPath, ".\data")):
    os.mkdir(os.path.join(absPath, ".\data"))
dataPath = os.path.normpath(os.path.join(absPath, ".\data\data.json"))


class MyMainWindow(QMainWindow):
    def __init__(self):
        super(MyMainWindow, self).__init__()
        # super(MathPlot, self).__init__()
        self.selectedTemplate = None
        self.dataBase = DataJson(dataPath)
        self.main_canve = MainUI()
        self.setCentralWidget(self.main_canve)
        self.initDataForUI()

        self.main_canve.addCode.connect(self.AddCode)
        self.main_canve.searchCode.connect(self.SearchCodeByInput)
        self.main_canve.searchCodeByQRCode.connect(self.SearchCodeByQRCode)
        self.main_canve.searchCodeByScreen.connect(self.ScreenShotWindow)
        self.main_canve.addTemplate.connect(self.AddTemplate)
        self.main_canve.QRCodeListItemDelete.connect(self.QRCodeListItemDelete)
        self.main_canve.QRCodeListItemClicked.connect(self.QRCodeListItemClicked)
        self.main_canve.deleteTemplate.connect(self.DeleteTemplate)
        self.main_canve.updateSelectedTemplate.connect(self.UpdateSelectedTemplate)
        self.setGeometry(100, 100, 700, 700)
        self.setFixedSize(self.width(), self.height())
        self.setWindowTitle("编号管理")

    def initDataForUI(self):
        self.updateCodeList()
        self.updateTemplateList()
        self.UpdateSelectedTemplate()

    def updateCodeList(self):
        self.main_canve.showStoredCode.clear()
        for code in self.dataBase.CodeList():
            self.main_canve.showStoredCode.addItem(str(code))

    def updateTemplateList(self):
        templateList = self.dataBase.TemplateList()
        selected_template = [str(code) for code in templateList]
        self.main_canve.selected_template.clear()
        self.main_canve.selected_template.addItems(selected_template)

    def UpdateSelectedTemplate(self):
        current_template = self.main_canve.selected_template.currentText()
        for template in self.dataBase.TemplateList():
            if str(template) == current_template:
                self.selectedTemplate = template
        if self.selectedTemplate is None:
            return
        self.main_canve.input_edit.update(self.selectedTemplate)

    def updateQRCode(self, code: Code):
        self.main_canve.showQRCode.update(code)
        self.main_canve.search_edit.setText(str(code))

    def AddCode(self):
        code = self.main_canve.input_edit.getCode()
        template = self.selectedTemplate
        if not template.isChildren(code):
            QMessageBox.information(
                self,
                "提示",
                f"编号: {code} 不符合模板 {str(template)} 形式",
                QMessageBox.Ok,
            )
            return

        if self.dataBase.searchCode(code) is not None:
            QMessageBox.information(
                self, "提示", f"编号: {code} 已存在", QMessageBox.Ok
            )
            return
        self.dataBase.addCode(code)
        self.updateCodeList()
        self.updateQRCode(code)
        QMessageBox.information(self, "提示", f"成功添加编号: {code}", QMessageBox.Ok)

    def ScreenShotWindow(self):
        self.showMinimized()
        self.screenShotPix = None
        self.screenShot = WScreenShot(mainCanve=self)
        self.screenShot.showMaximized()
        self.screenShot.show()

    def SearchCodeByScreen(self):
        # TODO: 截图位置还有些不准确
        self.showNormal()
        self.screenShot.close()
        img = ImageQt.fromqpixmap(self.screenShotPix)
        decode_data = decode(img)
        if len(decode_data) == 0:
            QMessageBox.information(self, "提示", "未找到匹配的编号", QMessageBox.Ok)
            return
        code = decode(img)[0].data.decode("utf-8")
        self.SearchCode(code)

    def SearchCodeByQRCode(self):
        filePath, _ = QFileDialog.getOpenFileName(
            self, "Save Image", "", "Image files (*.jpg *.png)"
        )
        if filePath == "":
            return
        img = Image.open(filePath)
        code = decode(img)[0].data.decode("utf-8")
        self.SearchCode(code)

    def SearchCodeByInput(self):
        code = self.main_canve.search_edit.text()
        self.SearchCode(code)

    def SearchCode(self, code):
        resultCode = self.dataBase.searchCode(code)
        if resultCode is None:
            QMessageBox.information(self, "提示", "未找到匹配的编号", QMessageBox.Ok)
            return
        self.updateQRCode(resultCode)
        QMessageBox.information(
            self, "提示", f"找到匹配的编号: {resultCode}", QMessageBox.Ok
        )

    def AddTemplate(self):
        template = self.main_canve.settingWindow.fragmentTemplateScroll.GetTemplate()
        if self.dataBase.searchTemplate(template) is not None:
            QMessageBox.information(
                self, "提示", f"模板: {template} 已存在", QMessageBox.Ok
            )
            return
        if not self.isTemplateLegal(template):
            QMessageBox.information(
                self,
                "提示",
                f"模板: {template} 含有长度为0的编号段，创建失败",
                QMessageBox.Ok,
            )
            return
        self.dataBase.addTemplate(template)
        self.updateTemplateList()
        QMessageBox.information(
            self, "提示", f"成功添加模板: {template}", QMessageBox.Ok
        )

    def isTemplateLegal(self, template: CodeTemplate):
        if len(template.fragments) == 0:
            return False
        for fragment in template.fragments:
            if fragment.length == 0:
                QMessageBox.information(
                    self,
                    "提示",
                    f"模板: {template} 含有长度为0的编号段，创建失败",
                    QMessageBox.Ok,
                )
                return False
        return True

    def QRCodeListItemDelete(self):
        code_item = self.main_canve.showStoredCode.selectedItems()
        for item in code_item:
            code_txt = item.text()
            code = self.dataBase.searchCode(code_txt)
            self.dataBase.deleteCode(code)
        self.updateCodeList()

    def QRCodeListItemClicked(self):
        code_txt = self.main_canve.showStoredCode.currentItem().text()
        code = self.dataBase.searchCode(code_txt)
        self.updateQRCode(code)

    def DeleteTemplate(self):
        template = self.selectedTemplate
        self.dataBase.deleteTemplate(template)
        self.updateTemplateList()
        QMessageBox.information(
            self, "提示", f"成功删除模板: {template}", QMessageBox.Ok
        )

    def closeEvent(self, event):
        if (
            hasattr(self.main_canve, "settingWindow")
            and self.main_canve.settingWindow is not None
        ):
            self.main_canve.settingWindow.close()
        sys.exit(0)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    myWin = MyMainWindow()
    myWin.show()
    sys.exit(app.exec())
